home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / dev / misc / LEDA_gene.lha / LEDA-3.1c-generic / prog / graphics / polyhedron.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-05  |  6.3 KB  |  348 lines

  1. #include <LEDA/graph.h>
  2. #include <LEDA/graph_alg.h>
  3. #include <LEDA/array.h>
  4. #include <LEDA/stream.h>
  5. #include <LEDA/array.h>
  6. #include <LEDA/window.h>
  7. #include <math.h>
  8.  
  9.  
  10.  
  11. typedef GRAPH<vector,int> polyhedron;
  12.  
  13. void rotate(float alpha1,float alpha2, vector& p)
  14.   // rotate 3d-point p about the origin
  15.   // by alpha2 in yz-plane and alpha1 in xy-plane
  16.  
  17.     double R  = hypot(p[1],p[2]);
  18.     double phi = asin(p[1]/R);
  19.   
  20.     if (p[2] < 0) phi = M_PI - phi;
  21.   
  22.     p[1]  = ((R != 0) ? R*sin(phi+alpha2) : 0);
  23.     p[2]  = ((R != 0) ? R*cos(phi+alpha2) : 0);
  24.  
  25.     R   = hypot(p[0],p[2]);
  26.     phi = asin(p[0]/R);
  27.  
  28.     if (p[2] < 0) phi = M_PI - phi;
  29.   
  30.     p[0]  = ((R != 0) ? R*sin(phi+alpha1) : 0);
  31.     p[2]  = ((R != 0) ? R*cos(phi+alpha1) : 0);
  32. }
  33.  
  34.  
  35. point project(vector p)   // project p into xy-plane
  36. {
  37.   return point(p[0],p[1]); 
  38.  }
  39.  
  40.  
  41.  
  42. void draw_poly(window& W, polyhedron& poly, vector& trans)
  43. { node v,w;
  44.   node_array<bool> marked(poly,false);
  45.   forall_nodes(v,poly) 
  46.   { forall_adj_nodes(w,v)
  47.       if (!marked[w])
  48.       { point a = project(poly[v]+trans);
  49.         point b = project(poly[w]+trans);
  50.         W.draw_segment(a,b,blue);
  51.        }
  52.     marked[v] = true;
  53.    }
  54.  }
  55.  
  56. /*
  57. void draw_poly(window& W, polyhedron& poly, vector& trans)
  58. { edge e;
  59.   forall_edges(e,poly) 
  60.   { point a = project(poly[source(e)]+trans);
  61.     point b = project(poly[target(e)]+trans);
  62.     W.draw_segment(a,b,blue);
  63.    }
  64.  }
  65. */
  66.  
  67.  
  68. void make_poly(polyhedron& poly, int N)
  69.   
  70.     node* L = new node[N];
  71.     node* R = new node[N];
  72.   
  73.     float d = 2*M_PI/N;
  74.  
  75.     node v;
  76.  
  77.     poly.clear();
  78.   
  79.     for(int i=0; i<N; i++)
  80.     { point origin(0,0);
  81.       point p = origin.translate(i*d,100);
  82.       L[i] = poly.new_node(vector(p.xcoord(),p.ycoord(), 120));
  83.       R[i] = poly.new_node(vector(p.xcoord(),p.ycoord(),-120));
  84.      }
  85.  
  86.     node v0 = poly.new_node(vector(0,0,-30));
  87.   
  88.     for(i=1; i<N; i++)
  89.     { poly.new_edge(L[i],L[i-1]);
  90.       poly.new_edge(L[i-1],L[i]);
  91.       poly.new_edge(R[i],R[i-1]);
  92.       poly.new_edge(R[i-1],R[i]);
  93.       poly.new_edge(L[i],R[i]);
  94.       poly.new_edge(R[i],L[i]);
  95.       poly.new_edge(v0,R[i]);
  96.       poly.new_edge(R[i],v0);
  97.      }
  98.   
  99.     poly.new_edge(L[0],L[N-1]);
  100.     poly.new_edge(L[N-1],L[0]);
  101.     poly.new_edge(R[0],R[N-1]);
  102.     poly.new_edge(R[N-1],R[0]);
  103.     poly.new_edge(L[0],R[0]);
  104.     poly.new_edge(R[0],L[0]);
  105.     poly.new_edge(v0,R[0]);
  106.     poly.new_edge(R[0],v0);
  107.  
  108.     if (!PLANAR(poly,true)) error_handler(1,"graph not planar !");
  109.  
  110.     // compute an interior point M and move the origin to this point
  111.   
  112.     vector M(3);
  113.   
  114.     forall_nodes(v,poly)
  115.     {  M[0] += poly[v][0];
  116.        M[1] += poly[v][1];
  117.        M[2] += poly[v][2];
  118.      }
  119.   
  120.   
  121.     M[0] /= poly.number_of_nodes();
  122.     M[1] /= poly.number_of_nodes();
  123.     M[2] /= poly.number_of_nodes();
  124.   
  125.   
  126.     forall_nodes(v,poly)
  127.     { poly[v][0] -= M[0];
  128.       poly[v][1] -= M[1];
  129.       poly[v][2] -= M[2];
  130.      }
  131.   
  132. }
  133.  
  134.  
  135.  
  136. void make_sphere(GRAPH<vector,int>& G, int n)
  137. {
  138.   int m = 2*n;
  139.  
  140.   array<node>  V(m);
  141.  
  142.   node north = G.new_node(vector(0,0, 1));
  143.  
  144.   int i;
  145.   int j;
  146.   double phi1 = 0;
  147.   double phi2 = 0;
  148.   double d1 = M_PI/n;
  149.   double d2 = M_PI/n;
  150.  
  151.   for(i=0; i<m; i++) V[i] = north;
  152.  
  153.   for(phi1=d1, j=1; j<n; phi1+=d1, j++)
  154.   { double z = cos(phi1);
  155.     double r = sin(phi1);
  156.  
  157.     for(phi2=0, i=0; i<m; phi2+=d2, i++)
  158.     {
  159.       double x = r*cos(phi2);
  160.       double y = r*sin(phi2);
  161.  
  162.       node v = G.new_node(vector(x,y,z));
  163.  
  164.       if(i==0) 
  165.       { G.new_edge(v,V[i]);
  166.         G.new_edge(V[i],v);
  167.         if (j > 1)  
  168.         { G.new_edge(V[0],V[m-1]);
  169.           G.new_edge(V[m-1],V[0]);
  170.          }
  171.        }
  172.       else
  173.        { G.new_edge(v,V[i-1]);
  174.          G.new_edge(V[i-1],v);
  175.          G.new_edge(v,V[i]);
  176.          G.new_edge(V[i],v);
  177.         }
  178.       V[i] = v;
  179.      }
  180.  
  181.    }
  182.  
  183.   node south = G.new_node(vector(0,0,-1));
  184.  
  185.   G.new_edge(V[m-1],V[0]);
  186.   G.new_edge(V[0],V[m-1]);
  187.  
  188.   for (i=0;i<m;i++) 
  189.   { G.new_edge(south,V[i]);
  190.     G.new_edge(V[i],south);
  191.    }
  192.  
  193.  
  194.   node v;
  195.  
  196.   forall_nodes(v,G) G[v] = G[v]*100;
  197.  
  198.   if (!PLANAR(G,true)) error_handler(1," G not planar !");
  199.  
  200. }
  201.  
  202.  
  203.  
  204.  
  205.  
  206. void read_poly(polyhedron& poly, string fname)
  207. {
  208.   poly.clear();
  209.  
  210.   file_istream IN(fname);
  211.  
  212.   int N;
  213.   int i;
  214.  
  215.   IN >> N;
  216.  
  217.  
  218.   array<node> V(N);
  219.  
  220.   vector v(3);
  221.  
  222.   for(i = 0; i<N; i++) 
  223.   { IN >> v;
  224.     V[i] = poly.new_node(v);
  225.    }
  226.  
  227. /*
  228.   for(i = 0; i<N; i++) 
  229.   { int d;
  230.     IN >> d;
  231.     while(d--)
  232.     { IN >> j;
  233.       poly.new_edge(V[i], V[j])
  234.      }
  235.    }
  236. */
  237.  
  238.   for(i = 0; i<N; i++) 
  239.   { int u,v,w;
  240.     IN >> u >> v >> w;
  241.     poly.new_edge(V[u], V[v]);
  242.     poly.new_edge(V[v], V[w]);
  243.     poly.new_edge(V[w], V[u]);
  244.   }
  245.  
  246. }
  247.  
  248.  
  249.  
  250.  
  251. main()
  252.   window W(700,700);
  253.  
  254.   W.init(-250,250,-250);
  255.   W.set_node_width(4);
  256.   W.set_mode(xor_mode);
  257.  
  258.   node v;
  259.  
  260.   int     N = 5;
  261.   int speed = 40;
  262.   bool  ran = false;
  263.  
  264.  panel P("Rotate Polyhedron");
  265.  
  266.  P.text_item("");
  267.  P.text_item("This program creates and rotates a 3-dimensional polyhedron.");
  268.  P.text_item("Direction and duration of the rotation is controled by the");
  269.  P.text_item("left mouse button.");
  270.  P.text_item("");
  271.  P.bool_item("random",ran);
  272.  P.int_item("speed",speed,1,80);
  273.  P.int_item("# vertices",N,3,32);
  274.  
  275.  
  276.  
  277.  for(;;)
  278.  {
  279.     P.open(W);
  280.  
  281.     W.clear();
  282.  
  283.     // define a polyhedron in 3d space
  284.   
  285.     polyhedron poly;
  286.  
  287.     //make_poly(poly,N);
  288.     make_sphere(poly,N);
  289.   
  290.   
  291.   
  292.     forall_nodes(v,poly) rotate(1.5,0.7,poly[v]);
  293.  
  294.     W.draw_point(0,0);
  295.   
  296.   
  297.     polyhedron poly0 = poly;
  298.  
  299.     vector dir(2);   // direction and duration of rotation
  300.     //vector trans(50,50,50);  // translation
  301.     vector trans(0,0,0);  // translation
  302.     int steps;
  303.  
  304.     draw_poly(W,poly,trans);
  305.   
  306.     for(;;)
  307.     {
  308.       if (ran)
  309.       { dir[0] += random(-10000,10000)/(5000000.0);
  310.         dir[1] += random(-10000,10000)/(5000000.0);
  311.         dir = dir.norm()*(speed/500.0);
  312.         steps = 1;
  313.         if (W.get_button() != 0) break;
  314.        }
  315.       else
  316.       { int but = W.read_mouse(dir[0],dir[1]);
  317.         steps = int(dir.length()*W.scale())/8;
  318.         if (but == 3) break;
  319.         dir = dir.norm()*(speed/500.0);
  320.        }
  321.  
  322.   
  323.  
  324.       while (steps--)
  325.       {  
  326.         forall_nodes(v,poly) rotate(dir[0],dir[1],poly[v]);
  327.    
  328.         draw_poly(W,poly,trans);   // draw new position
  329.         draw_poly(W,poly0,trans);  // erase old position  (xor_mode !!)
  330.   
  331.         // poly0 = poly;
  332.   
  333.         node w = poly.first_node();
  334.         forall_nodes(v,poly0) 
  335.         { poly0[v] = poly[w];
  336.           w = poly.succ_node(w);
  337.          }
  338.       }
  339.     }
  340.  
  341.   }
  342.  
  343.  return 0;
  344. }
  345.